package com.elinkway.infinitemovies.adaction.download;

import android.app.IntentService;
import android.app.NotificationManager;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.graphics.BitmapFactory;
import android.net.Uri;
import android.os.Build;
import android.os.Environment;
import android.os.Handler;
import android.os.Message;
import android.support.v7.app.NotificationCompat;
import android.support.v4.content.FileProvider;

import com.elinkway.infinitemovies.application.MoviesApplication;
import com.elinkway.infinitemovies.utils.LogUtils;
import com.elinkway.infinitemovies.utils.NetWorkTypeUtils;
import com.elinkway.infinitemovies.utils.StorageManager;
import com.elinkway.infinitemovies.utils.StringUtil;
import com.elinkway.infinitemovies.utils.ToastUtil;
import com.elinkway.infinitemovies.utils.Utils;
import com.elinkway.infinitemovies.view.CustomDialog;
import com.le123.ysdq.R;
import com.nostra13.universalimageloader.core.ImageLoader;

import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.ArrayList;
import java.util.HashMap;

/**
 *
 * 互众、柚子广告 第三方app后台下载类
 */
public class DownloadService extends IntentService {
    private final static String TAG = "DownloadService";
    public static final int DOWNINGING = 0;
    private final static int DOWNLOAD_SUCCESS = 1;
    private final static int DOWNLOAD_FAIL = 2;
    private final static int START_DOWNLOAD_TOAST = 3;
    private final static int START_INSTALL_TOAST = 4;
    private final static int DOWNLOADING_TOAST = 5;
    private final static int NO_NET_TOAST = 6;
    private final static int OPEN_APP = 7;
    private final static int NO_WIFI = 8;
    private boolean mDownErr;
    private File downloadFile = null;

    //通知栏
    private NotificationManager downloadNotificationManager = null;
    private NotificationCompat.Builder downloadNotificationBuilder = null;
    private String mPackageName = "";
    private String appName = "";
    private String appIcon = "";
    private String downloadUrl = "";
    private ArrayList downloadUrls = null;
    private ArrayList downloadedUrls = null;
    private ArrayList installUrls = null;
    private HashMap downloadingApp = new HashMap();
    private CustomDialog.Builder openAppBuilder = null;
    private CustomDialog.Builder noWifiBuilder = null;
    private boolean isInnerWebviewDownload;
    private String mAdPos;

    private BroadcastReceiver mAppInstallReceiver;

    public DownloadService() {
        super("DownloadService");
    }

    @Override
    public void onCreate() {
        super.onCreate();
        LogUtils.d(TAG, "--------onCreate----------");
        downloadNotificationManager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
        IntentFilter intentFilter = new IntentFilter(Intent.ACTION_PACKAGE_ADDED);
        intentFilter.addDataScheme("package");
        mAppInstallReceiver = new AppInstallReceiver();
        registerReceiver(mAppInstallReceiver, intentFilter);
    }

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        LogUtils.d(TAG, "--------onStartCommand----------");
        downloadNotificationBuilder = new NotificationCompat.Builder(this);
        downloadNotificationBuilder.setSmallIcon(android.R.drawable.stat_sys_download)
                .setLargeIcon(BitmapFactory.decodeResource(getResources(), R.drawable.ic_notif_download_inner))
                .setAutoCancel(false);
        return super.onStartCommand(intent, flags, startId);
    }

    @Override
    public void onStart(Intent intent, int startId) {
        LogUtils.d(TAG, "--------onStart----------");
        if (downloadingApp.containsKey(downloadUrl)) {
            Message message = new Message();
            message.what = DOWNLOADING_TOAST;
            mHandler.sendMessage(message);
        } else {
            super.onStart(intent, startId);
        }
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        try {
            unregisterReceiver(mAppInstallReceiver);
        } catch (Exception e) {
            com.apkfuns.logutils.LogUtils.d(e.getMessage());
        }
    }

    @Override
    protected void onHandleIntent(Intent intent) {
        mPackageName = intent.getStringExtra("packageName");
        downloadUrl = intent.getStringExtra("url");
        appIcon = intent.getStringExtra("appIcon");
        appName = intent.getStringExtra("appName");
        isInnerWebviewDownload = intent.getBooleanExtra(Utils.IS_INNER_WEBVIEW_DOWNLOAD, false);
        mAdPos = intent.getStringExtra(Utils.AD_POS);
        downloadUrls = intent.getStringArrayListExtra(ReportADAppDownloadReceiver.DOWNLOAD_URLS);
        downloadedUrls = intent.getStringArrayListExtra(ReportADAppDownloadReceiver.DOWNLOADED_URLS);
        installUrls = intent.getStringArrayListExtra(ReportADAppDownloadReceiver.INSTALL_URLS);
        if (StringUtil.isEmpty(downloadUrl)) {
            return;
        }

        if (!StringUtil.isEmpty(mPackageName) && Utils.isAppInstalled(MoviesApplication.getInstance(), mPackageName)) {
            Message message = new Message();
            message.what = OPEN_APP;
            mHandler.sendMessage(message);
            return;
        }

        if (!StringUtil.isEmpty(mPackageName)) {
            File file = new File(Environment.getExternalStorageDirectory(), mPackageName);
            if (file.exists()) {
                installApk(file);
                return;
            }
        }

        if (NetWorkTypeUtils.getNetType() == NetWorkTypeUtils.NETTYPE_NO) {
            Message message = new Message();
            message.what = NO_NET_TOAST;
            mHandler.sendMessage(message);
        } else if (NetWorkTypeUtils.getNetType() != NetWorkTypeUtils.NETTYPE_WIFI
                && NetWorkTypeUtils.getNetType() != NetWorkTypeUtils.NETTYPE_NO) {
            Message message = new Message();
            message.what = NO_WIFI;
            mHandler.sendMessage(message);
        } else {
            downloadApp();
        }
    }

    private void downloadApp() {
        try {
            Message message = new Message();
            message.what = START_DOWNLOAD_TOAST;
            mHandler.sendMessage(message);
            if (isInnerWebviewDownload) {
                reportInnerWebviewStartDownload();
            } else {
                reportStartDownload(downloadUrls);
            }
            startDownloadNotification();
            mDownErr = false;
            downloadingApp.put(downloadUrl, DOWNINGING);
            downloadFile = startDownload(mPackageName, appIcon, downloadUrl);
        } catch (IOException e) {
            e.printStackTrace();
        }
        if (null != downloadFile) {
            Message message = new Message();
            message.what = DOWNLOAD_SUCCESS;
            mHandler.sendMessage(message);
        }
    }

    protected Handler mHandler = new Handler() {
        @Override
        public void handleMessage(Message msg) {
            super.handleMessage(msg);
            switch (msg.what) {
                case DOWNINGING:
                    ToastUtil.showLongToast(MoviesApplication.getInstance(), R.string.downloading_app);
                    break;
                case DOWNLOAD_SUCCESS:
                    if (isInnerWebviewDownload) {
                        reportInnerWebviewDownloadSuccess();
                    } else {
                        reportDownloadSuccess(downloadedUrls);
                    }
                    if (downloadingApp.containsKey(downloadUrl)) {
                        downloadingApp.remove(downloadUrl);
                    }
                    if (downloadFile.exists()) {
                        installApk(downloadFile);
                        if (isInnerWebviewDownload) {
                            reportInnerWebviewStartInstall();
                            mPackageName = getDownloadFilePackageName(downloadFile);
                        }
                    }
                    break;
                case START_DOWNLOAD_TOAST:
                    ToastUtil.showLongToast(MoviesApplication.getInstance(), getString(R.string.start_download_app, appName));
                    break;
                case START_INSTALL_TOAST:
                    ToastUtil.showLongToast(MoviesApplication.getInstance(), getString(R.string.start_install_app, appName));
                    break;
                case DOWNLOADING_TOAST:
                    ToastUtil.showLongToast(MoviesApplication.getInstance(), R.string.downloading_app);
                    break;
                case NO_NET_TOAST:
                    ToastUtil.showLongToast(MoviesApplication.getInstance(), R.string.nonet_tip);
                    break;
                case OPEN_APP:
                    initOpenAppDialog();
                    break;
                case DOWNLOAD_FAIL:
                    break;
                case NO_WIFI:
                    initNoWifiDialog();
                    break;
                default:
                    break;
            }
        }
    };

    private File startDownload(String packageName, String appIcon, String downloadUrl) throws IOException {
        int downloadCount = 0;
        URL url = new URL(downloadUrl);
        HttpURLConnection conn = (HttpURLConnection) url.openConnection();
        conn.setConnectTimeout(6000);
        conn.setReadTimeout(6000);
        //获取到文件的大小
        int total_size = conn.getContentLength();
        LogUtils.e(TAG, "total_size is " + total_size);
        // 重试机制
        if (total_size <= 0) {
            return null;
        }
        downloadNotificationBuilder.setOngoing(true)
                .setProgress(100, 0, false).setContentText("正在下载");
        downloadNotificationManager.notify(1, downloadNotificationBuilder.build());
        InputStream is = conn.getInputStream();
        File file;
        if (StringUtil.isEmpty(packageName)) {
            file = new File(Environment.getExternalStorageDirectory(), "" + System.currentTimeMillis());
        } else {
            file = new File(Environment.getExternalStorageDirectory(), packageName);
        }
        if (file.exists()) {
            boolean status = file.delete();
        }
        BufferedInputStream bis = new BufferedInputStream(is);
        FileOutputStream fos = new FileOutputStream(file);
        byte[] buffer = new byte[1024];
        int len;
        int current_size = 0;
        while ((len = bis.read(buffer)) != -1) {

            fos.write(buffer, 0, len);
            current_size += len;
            //获取当前下载量
            int current_progress = (current_size * 100) / total_size;
            if ((downloadCount == 0)
                    || current_progress - 10 > downloadCount) {
                downloadCount += 10;
                downloadNotificationBuilder
                        .setProgress(100, current_progress, false)
                        .setLargeIcon(BitmapFactory.decodeResource(getResources(), R.drawable.ic_notif_download_inner))
                        .setContentText(
                                String.format(
                                        "正在下载 %1$s/%2$s",
                                        StorageManager.bytes2humanity(current_size),
                                        StorageManager.bytes2humanity(total_size)));
                downloadNotificationManager.notify(1,
                        downloadNotificationBuilder.build());
            }
        }
        fos.close();
        bis.close();
        is.close();

        if (current_size != total_size) {
            mDownErr = true;
            if (file.exists()) {
                file.delete();
            }
            downloadingApp.remove(downloadUrl);
            Message message = new Message();
            message.what = DOWNLOAD_FAIL;
            mHandler.sendMessage(message);
            LogUtils.e(TAG, "current_size is part or net is weak");
            return null;
        }
        return file;
    }

    private void startDownloadNotification() {
        downloadNotificationBuilder.setProgress(0, 0, true)
                .setOngoing(true)
                .setSmallIcon(android.R.drawable.stat_sys_download)
                .setLargeIcon(BitmapFactory.decodeResource(getResources(), R.drawable.ic_notif_download_inner))
                .setTicker("开始下载")
                .setContentText("正在连接");
        downloadNotificationManager.notify(1, downloadNotificationBuilder.build());
    }

    private void initNoWifiDialog() {
        try {
            if (noWifiBuilder == null) {
                noWifiBuilder = new CustomDialog.Builder(MoviesApplication.getInstance().getTopActivity());
                noWifiBuilder.setMessage(getString(R.string.download_app_tip));
                noWifiBuilder.setPositiveButton(R.string.download_sure, new DialogInterface.OnClickListener() {
                    @Override
                    public void onClick(DialogInterface dialog, int which) {
                        downloadApp();
                        dialog.dismiss();
                    }
                });
                noWifiBuilder.setNegativeButton(R.string.download_cancel, new DialogInterface.OnClickListener() {

                    @Override
                    public void onClick(DialogInterface dialog, int which) {
                        dialog.dismiss();
                    }
                });
            }
            noWifiBuilder.create().show();
        } catch (Exception e) {
            com.apkfuns.logutils.LogUtils.d(e.getMessage());
        }
    }

    private void initOpenAppDialog() {
        try {
            if (openAppBuilder == null) {
                openAppBuilder = new CustomDialog.Builder(MoviesApplication.getInstance().getTopActivity());
                openAppBuilder.setMessage(getString(R.string.open_app, appName));
                openAppBuilder.setPositiveButton(R.string.download_sure, new DialogInterface.OnClickListener() {
                    @Override
                    public void onClick(DialogInterface dialog, int which) {
                        try {
                            Intent intent = DownloadService.this.getPackageManager().getLaunchIntentForPackage(mPackageName);
                            startActivity(intent);
                            dialog.dismiss();
                        } catch (Exception e) {

                        }
                    }
                });
                openAppBuilder.setNegativeButton(R.string.download_cancel, new DialogInterface.OnClickListener() {

                    @Override
                    public void onClick(DialogInterface dialog, int which) {
                        dialog.dismiss();
                    }
                });
            }
            openAppBuilder.create().show();
        } catch (Exception e) {
            com.apkfuns.logutils.LogUtils.d(e.getMessage());
        }
    }

    //安装apk
    private void installApk(File file) {
        if (null == file) {
            return;
        }
        Intent intent = new Intent();
        //执行动作
        intent.setAction(Intent.ACTION_VIEW);
        //执行的数据类型
        intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);

        if (Build.VERSION.SDK_INT >= 24) {
            intent.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
            Uri contentUri = FileProvider.getUriForFile(this, this.getPackageName(), file);
            intent.setDataAndType(contentUri, "application/vnd.android.package-archive");
        } else {
            intent.setDataAndType(Uri.fromFile(file), "application/vnd.android.package-archive");
        }

        this.startActivity(intent);
        if (downloadNotificationManager != null) {
            downloadNotificationManager.cancel(1);
        }
    }

    private void reportStartDownload(ArrayList downloadUrls) {
        Intent intent = new Intent();
        intent.setAction("com.sdk.download");
        intent.putExtra(ReportADAppDownloadReceiver.REPORT_TYPE, ReportADAppDownloadReceiver.ReportAppDownloadType.START_DOWNLOAD);
        intent.putStringArrayListExtra(ReportADAppDownloadReceiver.DOWNLOAD_URLS, downloadUrls);
        sendBroadcast(intent);
    }

    private void reportDownloadSuccess(ArrayList downloadedUrls) {
        Intent intent = new Intent();
        intent.setAction("com.sdk.download");
        intent.putExtra(ReportADAppDownloadReceiver.REPORT_TYPE, ReportADAppDownloadReceiver.ReportAppDownloadType.DOWNLOAD_SUCCESS);
        intent.putStringArrayListExtra(ReportADAppDownloadReceiver.DOWNLOADED_URLS, downloadedUrls);
        sendBroadcast(intent);

    }

    private void reportStartInstall(ArrayList startInstallUrls) {
        Intent intent = new Intent();
        intent.setAction("com.sdk.download");
        intent.putExtra(ReportADAppDownloadReceiver.REPORT_TYPE, ReportADAppDownloadReceiver.ReportAppDownloadType.START_INSTALL);
        intent.putStringArrayListExtra(ReportADAppDownloadReceiver.START_INSTALL_URLS, startInstallUrls);
        sendBroadcast(intent);
    }

    private void reportInstallSuccess(ArrayList installUrls) {
        Intent intent = new Intent();
        intent.setAction("com.sdk.download");
        intent.putExtra(ReportADAppDownloadReceiver.REPORT_TYPE, ReportADAppDownloadReceiver.ReportAppDownloadType.INSTALL_SUCCESS);
        intent.putStringArrayListExtra(ReportADAppDownloadReceiver.INSTALL_URLS, installUrls);
        sendBroadcast(intent);
    }

    private void reportInnerWebviewStartDownload() {
        Intent intent = new Intent();
        intent.setAction("com.sdk.download");
        intent.putExtra(Utils.AD_POS, mAdPos);
        intent.putExtra(ReportADAppDownloadReceiver.REPORT_TYPE, ReportADAppDownloadReceiver.ReportAppDownloadType.INNER_WEBVIEW_START_DOWNLOAD);
        sendBroadcast(intent);
    }

    private void reportInnerWebviewDownloadSuccess() {
        Intent intent = new Intent();
        intent.setAction("com.sdk.download");
        intent.putExtra(Utils.AD_POS, mAdPos);
        intent.putExtra(ReportADAppDownloadReceiver.REPORT_TYPE, ReportADAppDownloadReceiver.ReportAppDownloadType.INNER_WEBVIEW_DOWNLOAD_SUCCESS);
        sendBroadcast(intent);

    }

    private void reportInnerWebviewStartInstall() {
        Intent intent = new Intent();
        intent.setAction("com.sdk.download");
        intent.putExtra(Utils.AD_POS, mAdPos);
        intent.putExtra(ReportADAppDownloadReceiver.REPORT_TYPE, ReportADAppDownloadReceiver.ReportAppDownloadType.INNER_WEBVIEW_START_INSTALL);
        sendBroadcast(intent);
    }

    private void reportInnerWebviewInstallSuccess() {
        Intent intent = new Intent();
        intent.setAction("com.sdk.download");
        intent.putExtra(Utils.AD_POS, mAdPos);
        intent.putExtra(ReportADAppDownloadReceiver.REPORT_TYPE, ReportADAppDownloadReceiver.ReportAppDownloadType.INNER_WEBVIEW_INSTALL_SUCCESS);
        sendBroadcast(intent);
    }

    private String getDownloadFilePackageName(File file) {
        if (file!= null && file.exists()) {
            PackageManager pm = this.getPackageManager();
            PackageInfo info = pm.getPackageArchiveInfo(file.getAbsolutePath(), PackageManager.GET_ACTIVITIES);
            ApplicationInfo appInfo = null;
            if (info != null) {
                appInfo = info.applicationInfo;
                return appInfo.packageName;
            }
        }
        return null;
    }

    public class AppInstallReceiver extends BroadcastReceiver {
        PackageInfo packageInfo = null;

        @Override
        public void onReceive(Context context, Intent intent) {
            String packageName = intent.getData().getSchemeSpecificPart();
            com.apkfuns.logutils.LogUtils.d("upload download installed app:" + packageName);
            try {
                //获取应用名
                packageInfo = context.getPackageManager().getPackageInfo(packageName, 0);
                ApplicationInfo appInfo = null;
                if (packageInfo != null) {
                    appInfo = packageInfo.applicationInfo;
                    if (mPackageName != null && mPackageName.equals(appInfo.packageName)) {
                        if (isInnerWebviewDownload) {
                            reportInnerWebviewInstallSuccess();
                        } else {
                            reportInstallSuccess(installUrls);
                        }
                    }
                }
            } catch (PackageManager.NameNotFoundException e) {
                e.printStackTrace();
            }
        }
    }
}
